package com.oro.domain;

import static javax.persistence.CascadeType.ALL;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Entity;
import javax.persistence.JoinTable;
import javax.persistence.ManyToOne;

/**
 * Entity implementation class for Entity: Iscrizione
 * 
 */
@Entity
public class Iscrizione extends Proposal implements Serializable {

	private static final long serialVersionUID = 1L;

	@ManyToOne(cascade = ALL)
	@JoinTable(name = "iscrizione_corso")
	private Corso corso;

	private Date endDate;

	private int numWeeks;

	private Date startDate;

	@ManyToOne(cascade = ALL)
	@JoinTable(name = "iscrizione_studente")
	private Studente studente;

	private float weeklyCost; // We store it here because, if the course weekly
								// price changes in the future, this must not
								// change
								// anyway.

	public Iscrizione() {
		super();
		setCanOverrideTotalCost(true);
		setCanPercentageTotalCost(true);
		setCanSubtractTotalCost(true);
		setCanOverrideWeeklyCost(true);
		setCanPercentageWeeklyCost(true);
		setCanSubtractWeeklyCost(true);
	}

	public Iscrizione(Studente stud, Corso cor) {
		this();
		setStudente(stud);
		setCorso(cor);
		if (getCorso() != null) {
			setWeeklyCost(corso.getWeeklyCost(getNumWeeks()));
			setTotalCost(getNumWeeks() * getWeeklyCost());
		}
	}

	@Override
	public boolean equals(Object o) {
		if (this == o)
			return true;
		if (o == null)
			return false;
		if (!(o instanceof Iscrizione))
			return false;
		Iscrizione i = (Iscrizione) o;
		if (getId() != null)
			return getId().equals(i.getId());
		else
			return studente.getId().equals(i.getStudente().getId())
					&& corso.getId().equals(i.getCorso().getId());
	}

	@Override
	public boolean getCanOverrideTotalCost() {
		return true;
	}

	@Override
	public boolean getCanOverrideWeeklyCost() {
		return true;
	}

	@Override
	public boolean getCanPercentageTotalCost() {
		return true;
	}

	@Override
	public boolean getCanPercentageWeeklyCost() {
		return true;
	}

	@Override
	public boolean getCanSubtractTotalCost() {
		return true;
	}

	@Override
	public boolean getCanSubtractWeeklyCost() {
		return true;
	}

	public Corso getCorso() {
		return corso;
	}

	@Override
	public float getDiscountedCost() {
		float result = getTotalCost();
		if (getCanPercentageWeeklyCost())
			result = getWeeklyCost()
					* (100 - getDiscount().getPercentageWeeklyCost()) / 100
					* getNumWeeks();
		if (getCanSubtractWeeklyCost())
			result = (getWeeklyCost() - getDiscount().getSubtractWeeklyCost())
					* (100 - getDiscount().getPercentageWeeklyCost()) / 100
					* getNumWeeks();
		if (getCanOverrideWeeklyCost())
			if (!(getDiscount().getOverrideWeeklyCost() < 0))
				result = getDiscount().getOverrideWeeklyCost() * getNumWeeks();
		if (getCanPercentageTotalCost())
			result = result * (100 - getDiscount().getPercentageTotalCost())
					/ 100;
		if (getCanSubtractTotalCost())
			result = result - getDiscount().getSubtractTotalCost();
		if (getCanOverrideTotalCost())
			if (!(getDiscount().getOverrideTotalCost() < 0))
				result = getDiscount().getOverrideTotalCost();
		return result;
	}

	public Date getEndDate() {
		return endDate;
	}

	public int getNumWeeks() {
		return numWeeks;
	}

	public Date getStartDate() {
		return startDate;
	}

	public Studente getStudente() {
		return studente;
	}

	@Override
	public float getTotalCost() {
		return getWeeklyCost() * getNumWeeks();
	}

	public float getWeeklyCost() {
		return weeklyCost;
	}

	@Override
	public void setCanOverrideTotalCost(boolean canOverrideTotalCost) {

	}

	@Override
	public void setCanOverrideWeeklyCost(boolean canOverrideWeeklyCost) {

	}

	@Override
	public void setCanPercentageTotalCost(boolean canPercentageTotalCost) {

	}

	@Override
	public void setCanPercentageWeeklyCost(boolean canPercentageWeeklyCost) {

	}

	@Override
	public void setCanSubtractTotalCost(boolean canOrNot) {
	}

	@Override
	public void setCanSubtractWeeklyCost(boolean canSubtractWeeklyCost) {
	}

	public void setCorso(Corso corso) {
		this.corso = corso;
		if (getCorso() != null) {
			setWeeklyCost(corso.getWeeklyCost(getNumWeeks()));
			setTotalCost(getNumWeeks() * getWeeklyCost());
		}
	}

	public void setEndDate(Date endDate) {
		this.endDate = endDate;
	}

	public void setNumWeeks(int numWeeks) {
		this.numWeeks = numWeeks;
		if (getCorso() != null) {
			setWeeklyCost(corso.getWeeklyCost(getNumWeeks()));
			setTotalCost(getNumWeeks() * getWeeklyCost());
		}
	}

	public void setStartDate(Date startDate) {
		this.startDate = startDate;
	}

	public void setStudente(Studente studente) {
		this.studente = studente;
	}

	public void setWeeklyCost(float weeklyCost) {
		this.weeklyCost = weeklyCost;
	}

}
